﻿#include "process.h"
#include<iostream>
#include<QMessageBox>
using namespace std;

void process::processinit(){
    runhead=new PPCB;   //运行队列的表头和表尾 及初始化
    runrear=new PPCB;
    runhead->next=runrear;
    runrear->pre=runhead;

    waithead=new PPCB;   //等待队列的表头和表尾  及初始化
    waitrear=new PPCB;
    waithead->next=waitrear;
    waitrear->pre=waithead;

    readyhead=new PPCB;   //就绪队列的表头和表尾 及初始化
    readyrear=new PPCB;
    readyhead->next=readyrear;
    readyrear->pre=readyhead;

    blockhead=new PPCB;   //阻塞队列的表头和表尾 及初始化
    blockrear=new PPCB;
    blockhead->next=blockrear;
    blockrear->pre=blockhead;

    finishhead=new PPCB;   //完成队列的表头和表尾 及初始化
    finishrear=new PPCB;
    finishhead->next=finishrear;
    finishrear->pre=finishhead;

    for(int a=1;a<=10;a++)   //模拟10个进程 先放进去两个队列中 已便演示
    {
       New_process(0,0,0,0);
    }
    //Show_process();

}

PPCB* process::Find_pro_byId(int id){
    PPCB *p=new PPCB;
    p=runhead->next;
    while((p!=runrear))
    {
        if(p->id==id)
        {
            return p;
        }
        p=p->next;
    }
    p=waithead->next;
    while((p!=waitrear))
    {
        if(p->id==id)
        {
            return p;
        }
        p=p->next;
    }
    p=readyhead->next;
    while((p!=readyrear))
    {
        if(p->id==id)
        {
            return p;
        }
        p=p->next;
    }
    p=blockhead->next;
    while((p!=blockrear))
    {
        if(p->id==id)
        {
            return p;
        }
        p=p->next;
    }
    p=finishhead->next;
    while((p!=finishrear))
    {
        if(p->id==id)
        {
            return p;
        }
        p=p->next;
    }

    return NULL;
}

PPCB* process::Find_pro_byfileId(int fileid){
    PPCB *p=new PPCB;
    p=runhead->next;
    while((p!=runrear))
    {
        if(p->file_id==fileid)
        {
            return p;
        }
        p=p->next;
    }
    p=waithead->next;
    while((p!=waitrear))
    {
        if(p->file_id==fileid)
        {
            return p;
        }
        p=p->next;
    }
    p=readyhead->next;
    while((p!=readyrear))
    {
        if(p->file_id==fileid)
        {
            return p;
        }
        p=p->next;
    }
    p=blockhead->next;
    while((p!=blockrear))
    {
        if(p->file_id==fileid)
        {
            return p;
        }
        p=p->next;
    }
    p=finishhead->next;
    while((p!=finishrear))
    {
        if(p->file_id==fileid)
        {
            return p;
        }
        p=p->next;
    }

    return NULL;
}

PPCB* process::Delete_process_byId(int id,int state){
    PPCB* p=new PPCB;
    p= Find_pro_byId(id);
    p->pre->next=p->next;
    p->next->pre=p->pre;
    switch (state) {
    case 1:
        run_count--;
        break;
    case 2:
        wait_count--;
        break;
    case 3:
        ready_count--;
        break;
    case 4:
        block_count--;
        break;
    case 5:
        finish_count--;
        break;
    default:break;
    }
    return p;
}

void process::Insert_run(PPCB *p){
    p->state=1;
    runrear->pre->next=p;
    p->pre=runrear->pre;
    p->next=runrear;
    runrear->pre=p;
    run_count++;
}

void process::Insert_wait(PPCB *p){
    p->state=2;
    waitrear->pre->next=p;
    p->pre=waitrear->pre;
    p->next=waitrear;
    waitrear->pre=p;
    wait_count++;
}

void process::Insert_ready(PPCB *p){
    p->state=3;
    readyrear->pre->next=p;
    p->pre=readyrear->pre;
    p->next=readyrear;
    readyrear->pre=p;
    ready_count++;
}

void process::Insert_block(PPCB *p){
    p->state=4;
    blockrear->pre->next=p;
    p->pre=blockrear->pre;
    p->next=blockrear;
    blockrear->pre=p;
    block_count++;
}

void process::Insert_finish(PPCB *p){
    p->state=5;
    finishrear->pre->next=p;
    p->pre=finishrear->pre;
    p->next=finishrear;
    finishrear->pre=p;
    finish_count++;
}

PPCB* process::New_process(int cputime,int priority,int mem,int file_id){
    if(cputime==0){
        cputime=rand()%20+1;
    }
    if(mem==0){
        mem=rand()%400+20;
    }
    if(priority==0){
        priority=rand()%5+1;
    }

    PPCB* new_pro= new struct PPCB;
    new_pro->id=processid++;
    new_pro->memory=mem;
    new_pro->cputime=cputime;
    new_pro->lefttime=cputime;
    new_pro->priority=priority;
    new_pro->file_id=file_id;
    new_pro->time_count=0;

    Insert_wait(new_pro);
    //Insert_ready(new_pro);
    return new_pro;
}

void process::Time_out(){
    PPCB *p=new PPCB;
    PPCB *q=new PPCB;
    p=waithead->next;
    while((p!=waitrear))
    {
        p->time_count++;
        if(p->time_count>Out_time){
            q=p;
            p=p->next;
            Delete_process_byId(q->id,q->state);
        }
        else p=p->next;
    }
}

void process::block_process(int id){
    PPCB *p;
    p=Find_pro_byId(id);
    Delete_process_byId(id,p->state);
    Insert_block(p);
}

void process::wakeup_process(int id){
    PPCB* p;
    p=Find_pro_byId(id);
    Delete_process_byId(id,4);
    Insert_ready(p);
}

void process::Swap_process(PPCB *p, PPCB *q){
    PPCB* node=new PPCB;
    node=p;
    p->pre=q->pre;
    p->next=q->next;
    q->pre->next=p;
    q->next->pre=p;
    q->pre=node->pre;
    q->next=node->next;
    node->pre->next=q;
    node->next->pre=q;

}

void process::Fcfs(){
    PPCB* p=new PPCB;
    p=runhead->next;
    while(p!=runrear){
        p->lefttime=p->lefttime-timeslip;
        if(p->lefttime<=0){
            PPCB *q=new PPCB;
            q=p;
            p=p->next;
            Insert_finish(Delete_process_byId(q->id,q->state));//进程结束，需要和内存模块对接
        }
        else p=p->next;
    }
    while(run_count<run_max){
        if(readyhead->next!=readyrear){
            Insert_run(Delete_process_byId(readyhead->next->id,readyhead->next->state));
        }
        else{
            break;
        }
    }
}

PPCB* process::Find_next_fcfs_priority(){
    PPCB *p=new PPCB;
    PPCB *q=new PPCB;
    p=readyhead->next;
    q=readyhead->next;
    while(p!=readyrear){
        if(q->priority<p->priority){
            q=p;
        }
        p=p->next;
    }
    return q;
}

void process::Fcfs_Priority(){
    PPCB* p=new PPCB;
    p=runhead->next;
    while(p!=runrear){
        p->lefttime=p->lefttime-timeslip;
        if(p->lefttime<=0){
            PPCB *q=new PPCB;
            q=p;
            p=p->next;
            Insert_finish(Delete_process_byId(q->id,q->state));//进程结束，需要和内存模块对接
        }
        else p=p->next;
    }
    while(run_count<run_max){
        if(readyhead->next!=readyrear){
            Insert_run(Delete_process_byId(Find_next_fcfs_priority()->id,Find_next_fcfs_priority()->state));
        }
        else{
            break;
        }
    }
}

void process::R_r(){
    PPCB* p=new PPCB;
    p=runhead->next;
    while(p!=runrear){
        p->lefttime=p->lefttime-timeslip;
        if(p->lefttime<=0){
            PPCB *q=new PPCB;
            q=p;
            p=p->next;
            Insert_finish(Delete_process_byId(q->id,q->state));//进程结束，需要和内存模块对接
        }
        else{
            PPCB *q=new PPCB;
            q=p;
            p=p->next;
            Insert_ready(Delete_process_byId(q->id,q->state));//进程结束，需要和内存模块对接
        }

    }
    while(run_count<run_max){
        if(readyhead->next!=readyrear){
            Insert_run(Delete_process_byId(readyhead->next->id,readyhead->next->state));
        }
        else{
            break;
        }
    }

}

void process::Show_process(){
    PPCB* p=waithead->next;
    cout<<"wait_count="<<wait_count<<endl;
    while(p!=waitrear){

        cout<<p->id<<"      "<<p->cputime<<endl;
        p=p->next;
    }
}
